package cn.pping.service.impl;


import cn.pping.constants.RedisRegistConstant;
import cn.pping.domain.MessageSms;
import cn.pping.dto.RedisRegisterDto;
import cn.pping.exception.GlobalEnumCode;
import cn.pping.exception.GlobalException;
import cn.pping.prooerties.RegisterProperties;
import cn.pping.result.JSONResult;
import cn.pping.service.IMessageSmsService;
import cn.pping.service.IVerifyCodeService;
import cn.pping.util.AssertUtil;
import cn.pping.util.StrUtils;
import cn.pping.util.VerifyCodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    // 注入redis非关系性数据库
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RegisterProperties registerProperties;
    @Autowired
    private IMessageSmsService iMessageSmsService;

//    @Autowired
//    private SmsCodeConstants smsCodeConstants;

    /**
     * @Title: getVerifyCode 图像验证码
     * @Description: 图像验证码
     * @Author: Pan
     * @Version: 1.0
     * @Date: 2022/7/28 15:16
     * @Parameters: [key]
     * @Return java.lang.String
     */

    @Override
    public String getVerifyCode(String key) {
        // 判断前端穿进来的数据是否为空
        if (StringUtils.isEmpty(key)) {
            throw new GlobalException(GlobalEnumCode.COMMON_ERROR);
        }
        // 生成随机验证码
        String complexRandomString = StrUtils.getComplexRandomString(4);
        // 放入redis中 设置3分钟有效
        redisTemplate.opsForValue().set(key, complexRandomString, 3, TimeUnit.MINUTES);
        // 将生成的4位数和长宽转化为Base64位字节码
        return VerifyCodeUtils.verifyCode(100, 40, complexRandomString);
    }


    /**
     * @Title: sendSmsCode
     * @Description: 手机验证
     * @Author: Pan
     * @Version: 1.0
     * @Date: 2022/8/28 22:15
     * @Parameters: [poonecode]
     * @Return void
     */

    @Override
    public void sendSmsCode(String moblie) {
        Date date = new Date();
        // 校验图形验证码
        // 校验手机验证码
        // 判断手机号是否为空
        AssertUtil.isPhone(moblie, GlobalEnumCode.PHONE_ERROR);
        // 从redis中获取vlaue  register:%S = register:电话号码 通过占位符填写Key
        String key = String.format(RedisRegistConstant.PHONE_REGISTER_PREFIX, moblie);
        // 获取value
        Object value = redisTemplate.opsForValue().get(key);
        // 声明一个空的变量code
        String code = null;
        // 当前时间
        Long nowTime = System.currentTimeMillis();
        // 如果没有值的话就为空生成一个六位数的验证码
        if (value != null) {// 说有值判断是否超过一分钟（在升级版中我们需要通过对象进行转所以需要强转）
            // 将获取到的Vlue转换为对象
            RedisRegisterDto redisRegisterDto = (RedisRegisterDto) value;
            // 判断时间是否超过了一分钟
            if (nowTime - redisRegisterDto.getDateTime() < registerProperties.getInterval()) {
                throw new GlobalException(GlobalEnumCode.PHONE_REPEAT_SENDING);
            }
              code = redisRegisterDto.getCode();
        } else {
            // 生成验证码
            code = StrUtils.getRandomString(registerProperties.getCodesize());
        }
        // 重新发送验证码
        RedisRegisterDto redisVal = new RedisRegisterDto(code, date.getTime());
        redisTemplate.opsForValue().set(key, redisVal, registerProperties.getExpiration(), TimeUnit.MILLISECONDS);
        System.out.println(key);
        System.out.println(redisVal);
        // 发送短信
        String hint = String.format(registerProperties.getSmshint(), code);
        System.out.println(hint);
        // 保存日志

        extracted(date, hint);
    }

    private void extracted(Date date, String hint) {
        // 8.记录smsMessage数据库 // Ctrl+alit+m
        MessageSms messageSms = new MessageSms();
        messageSms.setTitle(registerProperties.getTitle());
        messageSms.setContent(hint);
        messageSms.setSendTime(date);
        // 获取浏览器数据
        // 设置IP
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        // 获取请求体 request
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        // 得到IP
        String remoteAddr = request.getRemoteAddr();
        messageSms.setIp(remoteAddr);
        iMessageSmsService.insert(messageSms);
    }
}